import 'dart:async';

import 'package:bot_toast/bot_toast.dart';
import 'package:trollee/app/components/custom_button.dart';
import 'package:trollee/app/components/dialog/app_dialog_animations.dart';
import 'package:trollee/app/core/core.dart';

/// 封装APP底部对话框
class AppBottomDialog {
  /// 显示文本对话框
  ///
  /// true 表示点击确认按钮  false表示点击取消按钮  null-表示只关闭未点击任何按钮
  static Future<bool?> showText({
    required String text,
    String? title,
    String? confirmText,
    VoidCallback? onConfirm,
    String? cancelText,
    VoidCallback? onCancel,
    bool showConfirm = true,
    bool showCancel = true,
  }) {
    return show(
      title: title,
      confirmText: confirmText,
      onConfirm: onConfirm,
      cancelText: cancelText,
      onCancel: onCancel,
      showCancel: showCancel,
      showConfirm: showConfirm,
      child: Text(text, style: AppTextStyles.body1_14_Regular_primary),
    );
  }

  /// 显示对话框
  ///
  /// true 表示点击确认按钮  false表示点击取消按钮  null-表示只关闭未点击任何按钮
  static Future<bool?> show({
    required Widget child,
    String? title,
    String? confirmText,
    VoidCallback? onConfirm,
    String? cancelText,
    VoidCallback? onCancel,
    bool showConfirm = true,
    bool showCancel = true,
  }) {
    return showCustomView(
      child: (cancelFunc, completer) => _AppBottomDialogWidget(
        cancelFunc: cancelFunc,
        title: title,
        confirmText: confirmText,
        onConfirm: onConfirm,
        cancelText: cancelText,
        onCancel: onCancel,
        completer: completer,
        showCancel: showCancel,
        showConfirm: showConfirm,
        child: child,
      ),
    );
  }

  /// 底部自定义弹窗
  static Future<T?> showCustomView<T>({
    required Widget Function(CancelFunc cancelFunc, Completer<T?> completer) child,
    Color backgroundColor = Colors.black38,
    bool allowClick = false,
    bool clickClose = false,
    bool crossPage = true,
    UniqueKey? key,
  }) {
    final completer = Completer<T?>();
    BotToast.showAnimationWidget(
      toastBuilder: (CancelFunc cancelFunc) => child.call(
        cancelFunc,
        completer,
      ),
      animationDuration: 200.milliseconds,
      onlyOne: true,
      clickClose: clickClose,
      allowClick: allowClick,
      crossPage: crossPage,
      key: key,
      enableKeyboardSafeArea: false,
      backButtonBehavior: BackButtonBehavior.ignore,
      backgroundColor: backgroundColor,
      wrapAnimation: (controller, cancel, child) => DialogOpacityAnimation(controller: controller, child: child),
      wrapToastAnimation: (controller, cancel, child) => DialogBottomUpAnimation(controller: controller, child: child),
      onClose: () {
        if (!completer.isCompleted) {
          completer.complete(null);
        }
      },
    );
    return completer.future;
  }
}

class _AppBottomDialogWidget extends StatelessWidget {
  const _AppBottomDialogWidget({
    required this.child,
    required this.cancelFunc,
    required this.completer,
    Key? key,
    this.title,
    this.confirmText,
    this.onConfirm,
    this.cancelText,
    this.onCancel,
    this.showConfirm = true,
    this.showCancel = true,
  }) : super(key: key);

  final String? title;
  final Widget child;
  final String? confirmText;
  final VoidCallback? onConfirm;
  final bool showConfirm;
  final String? cancelText;
  final VoidCallback? onCancel;
  final bool showCancel;
  final CancelFunc cancelFunc;
  final Completer<bool?> completer;

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.bottomCenter,
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: AppDimens.dp16),
        decoration: const BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
        ),
        constraints: BoxConstraints(maxHeight: AppDimens.sh - AppDimens.dp84),
        child: _body(),
      ),
    );
  }

  Widget _body() {
    final children = <Widget>[SizedBox(height: AppDimens.dp32)];

    if (title?.isNotEmpty == true) {
      children.addAll([
        Text(title!, style: AppTextStyles.text_20_Bold_primary),
        SizedBox(height: AppDimens.dp24),
      ]);
    }
    children.addAll([
      Flexible(
        child: SingleChildScrollView(
          physics: const BouncingScrollPhysics(),
          child: child,
        ),
      ),
      SizedBox(
        height: AppDimens.dp32,
      ),
      _buttons(),
      SizedBox(height: AppDimens.bbhSafe + AppDimens.dp12),
    ]);

    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: children,
    );
  }

  Widget _buttons() {
    final children = <Widget>[];

    if (showConfirm) {
      children.add(CustomButton.big(
        text: confirmText ?? 'general_btn_ok'.tr,
        onPressed: () {
          onConfirm?.call();
          completer.complete(true);
          cancelFunc.call();
        },
      ));
    }

    if (showCancel) {
      children.addAll([
        if (showConfirm) AppGaps.vGap8,
        CustomButton.small(
          text: cancelText ?? 'general_btn_cancel'.tr,
          height: AppDimens.dp40,
          full: false,
          borderColor: Colors.transparent,
          onPressed: () {
            onCancel?.call();
            completer.complete(false);
            cancelFunc.call();
          },
        )
      ]);
    }

    return Column(mainAxisSize: MainAxisSize.min, children: children);
  }
}
